/*
 * @Author: LIFM0623 1944099171@qq.com
 * @Date: 2024-02-24 16:13:45
 * @LastEditors: EyeSklear 1814580085@qq.com
 * @LastEditTime: 2024-05-15 21:15:06
 * @FilePath: \Scene_Back\src\group\group.service.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import { Injectable } from '@nestjs/common';
import { UpdateGroupDto } from './dto/update-group.dto';
import { RawGroupDto } from './dto/create-group.dto';
import { Group } from './entities/group.entity';
import { And, In, Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { RawUserToGroupDto } from 'src/group/dto/create-usertogroup.dto';
import { userRoleEnum } from 'src/enums/userRoleEnum';
import { generateRandomInviteCode } from 'src/utils/CommonUtils';
import { usertogroup } from 'src/group/entities/usertogroup.entity';
import { UpdateUserToGroupDto } from 'src/group/dto/update-usertogroup.dto';
import { FileListService } from 'src/file-list/file-list.service';
import { GroupToFlielist } from 'src/file-list/entities/grouptofilelist.entity';
import { User } from 'src/user/entities/user.entity';
import { UpdateFileListDto } from 'src/file-list/dto/update-file-list.dto';
import { FileList } from 'src/file-list/entities/file-list.entity';
import { CreateFileListDto } from 'src/file-list/dto/create-file-list.dto';
import * as fsExtra from 'fs-extra';
import { UpdateGroupToFilelistDto } from 'src/file-list/dto/update-grouptofilelist.dto';
import { SceneListService } from 'src/scene-list/scene-list.service';
import { SceneList } from 'src/scene-list/entities/scene-list.entity';
import { GroupToScence } from 'src/scene-list/entities/grouptoscene.entity';
import { UpdateGroupToScenceListDto } from 'src/scene-list/dto/update-grouptoscene.dto';
import * as path from 'path';
import { Folder } from 'src/folder/entities/folder.entity';
import { FolderService } from 'src/folder/folder.service';
import { GroupToFolderlist } from 'src/folder/entities/grouptofolder.entity';
import { GroupToScript } from 'src/script-list/entities/grouptoscript.entity';
import { ScriptListService } from 'src/script-list/script-list.service';
import { GroupToShare } from 'src/share/entities/grouptoshare.entity';
import { ShareService } from 'src/share/share.service';
@Injectable()
export class GroupService {
  constructor(
    @InjectRepository(FileList)
    private readonly fileListRepository: Repository<FileList>,
    @InjectRepository(Group)
    private readonly groupRepository: Repository<Group>,
    @InjectRepository(usertogroup)
    private readonly usertogroupRepository: Repository<usertogroup>,
    private fileListService: FileListService,
    private sceneListService: SceneListService,
    @InjectRepository(GroupToFlielist)
    private readonly groupToFlielistRepository: Repository<GroupToFlielist>,
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    @InjectRepository(SceneList)
    private readonly sceneListRepository: Repository<SceneList>,
    @InjectRepository(GroupToScence)
    private readonly groupToScenceRepository: Repository<GroupToScence>,
    private folderService: FolderService,
    @InjectRepository(GroupToFolderlist)
    private readonly groupToFolderRepository: Repository<GroupToFolderlist>,
    @InjectRepository(GroupToScript)
    private readonly groupToScriptRepository: Repository<GroupToScript>,
    private scriptListService: ScriptListService,
    @InjectRepository(GroupToShare)
    private readonly groupToShareRepository: Repository<GroupToShare>,
    private shareService: ShareService,
  ) {}

  getGroupInfoById(id: string) {
    return this.groupRepository.find({ where: { id: id } });
  }

  async createGroup(rawGroupDto: RawGroupDto, user: Express.User) {
    const insertItem = this.groupRepository.create(rawGroupDto);
    const res = await this.groupRepository.insert(insertItem);
    // 同时插入 usertogroup 表格
    const rawUserToGroupDto = new RawUserToGroupDto();
    rawUserToGroupDto.groupnickname = (user as any).username;
    rawUserToGroupDto.groupuuid = res.identifiers[0].id;
    rawUserToGroupDto.useruuid = (user as any).id;
    rawUserToGroupDto.role = userRoleEnum.creator;
    this.createUserToGroupItem(rawUserToGroupDto);
    return '创建成功';
  }
  async getInviteCode(groupuuid: string) {
    const oldItem = await this.groupRepository.findOne({
      where: { id: groupuuid },
    });
    if (oldItem.code !== null) {
      return { invitecode: oldItem.code, expiration: oldItem.expiration };
    } else {
      const invitecode = generateRandomInviteCode(32);
      const expirationTimestamp = Date.now() + 30 * 24 * 60 * 60 * 1000; // 设置有效期为一个月后
      const expiration = new Date(expirationTimestamp);
      if (!oldItem) {
        return '该修改对象不存在';
      }
      oldItem.code = invitecode;
      oldItem.expiration = expiration;
      await this.groupRepository.save(oldItem);
      return { invitecode: oldItem.code, expiration: expiration };
    }
  }

  async refreshInviteCode(groupuuid: string) {
    const oldItem = await this.groupRepository.findOne({
      where: { id: groupuuid },
    });
    const invitecode = generateRandomInviteCode(32);
    const expirationTimestamp = Date.now() + 30 * 24 * 60 * 60 * 1000; // 设置有效期为一个月后
    const expiration = new Date(expirationTimestamp);
    if (!oldItem) {
      return '该修改对象不存在';
    }
    oldItem.code = invitecode;
    oldItem.expiration = expiration;
    await this.groupRepository.save(oldItem);
    return '刷新链接成功';
  }

  async isInviteCodeExpired(invitecode: string) {
    const oldItem = await this.groupRepository.findOne({
      where: { code: invitecode },
    });
    if (!oldItem || Date.now() > oldItem.expiration.getTime()) {
      return null;
    } else {
      return oldItem.group_name;
    }
  }

  async updateGroupInfo(
    id: string,
    updateGroupDto: UpdateGroupDto,
    useruuid: string,
  ) {
    const oldGroupItem = await this.groupRepository.findOne({
      where: { id: id },
    });
    const oldUserToGroupItem = await this.usertogroupRepository.findOne({
      where: { groupuuid: id, useruuid: useruuid },
    });
    if (!oldGroupItem || !oldUserToGroupItem) {
      return '该修改对象不存在';
    }
    const updateUserToGroupDto = new UpdateUserToGroupDto();
    updateUserToGroupDto.groupnickname = (updateGroupDto as any).groupnickname;
    const updateUserToGroup = Object.assign(
      oldUserToGroupItem,
      updateUserToGroupDto,
    );
    await this.usertogroupRepository.save(updateUserToGroup);
    const updateGroupItem = Object.assign(oldGroupItem, updateGroupDto);
    await this.groupRepository.save(updateGroupItem);
    return '修改属性成功';
  }
  async deleteGroup(groupuuid: string) {
    try {
      // 1. 删除小组成员
      await this.deleteGroupToUser(groupuuid);
      // 2.删除小组文件 通过小组id删
      const fileuuidList = await this.groupToFlielistRepository.find({
        where: { groupuuid: groupuuid },
        select: ['fileuuid'],
      });
      for (const item of fileuuidList) {
        await this.fileListService.deleteFileItemFromGroup(item.fileuuid);
      }
      // 3.删文件夹
      const folderuuidList = await this.groupToFolderRepository.find({
        where: { groupuuid: groupuuid },
        select: ['folderuuid'],
      });
      for (const item of folderuuidList) {
        await this.folderService.deleteFolderItemFromGroup(item.folderuuid);
      }
      // 4.删除场景
      const scenceuuidList = await this.groupToScenceRepository.find({
        where: { groupuuid: groupuuid },
        select: ['scenceuuid'],
      });
      for (const item of scenceuuidList) {
        await this.sceneListService.deleteScenceItemFromGroupByScenceuuid(
          item.scenceuuid,
        );
      }
      // 5.删除脚本
      const scriptuuidList = await this.groupToScriptRepository.find({
        where: { groupuuid: groupuuid },
        select: ['scriptuuid'],
      });
      for (const item of scriptuuidList) {
        await this.scriptListService.deleteScriptItemFromGroup(item.scriptuuid);
      }
      // 6.删除分享
      const shareuuidList = await this.groupToShareRepository.find({
        where: { groupuuid: groupuuid },
        select: ['shareuuid'],
      });
      for (const item of shareuuidList) {
        await this.shareService.removeShareItemOfGroupById(item.shareuuid);
      }
      // 7.删除小组
      await this.groupRepository.delete({ id: groupuuid });
      return '解散成功';
    } catch (e) {
      console.log(e);
      return '解散失败';
    }
  }

  async getUserIsCreatorCount(useruuid: string) {
    const res = await this.usertogroupRepository.find({
      where: { useruuid: useruuid, role: 'creator' },
    });
    return res.length;
  }

  async getUserToGroupInfo(useruuid: any) {
    const res = await this.usertogroupRepository.find({
      where: { useruuid: useruuid },
      order: { create_time: 'ASC' },
    });
    const mergeRes = [];
    for (let i = 0; i < res.length; i++) {
      const groupInfo = await this.groupRepository.find({
        where: { id: res[i].groupuuid },
      });
      const getGroupMemberTable = await this.usertogroupRepository.find({
        where: { groupuuid: res[i].groupuuid },
      });
      const temp = {
        id: res[i].id,
        useruuid: res[i].useruuid,
        groupnickname: res[i].groupnickname,
        groupuuid: res[i].groupuuid,
        role: res[i].role,
        group_id: groupInfo[0].group_id,
        group_name: groupInfo[0].group_name,
        announcement: groupInfo[0].announcement,
        isApply: groupInfo[0].isApply,
        avatar: groupInfo[0].avatar,
        joinWay: groupInfo[0].joinWay,
        peoplecount: getGroupMemberTable.length,
      };
      mergeRes[i] = temp;
    }

    return mergeRes;
  }

  async getGroupToUserInfo(groupuuid: string) {
    const orderByCase = `
      CASE
        WHEN role = 'creator' THEN 1
        WHEN role = 'collaborator' THEN 2
        WHEN role = 'manager' THEN 3
        WHEN role = 'member' THEN 4
        ELSE 5
      END
    `;

    const groupMemberList = await this.usertogroupRepository
      .createQueryBuilder('usertogroup')
      .where('usertogroup.groupuuid = :groupuuid', { groupuuid })
      .orderBy(orderByCase, 'ASC')
      .addOrderBy('usertogroup.create_time', 'ASC')
      .getMany();

    for (let i = 0; i < groupMemberList.length; i++) {
      const userInfo = await this.userRepository.findOne({
        where: { id: groupMemberList[i].useruuid },
      });
      (groupMemberList[i] as any).avatar = userInfo.avatar;
    }
    return groupMemberList;
  }

  async joinGroup(user: any, invitecode: string) {
    const groupItem = await this.groupRepository.findOne({
      where: { code: invitecode },
    });
    const oldItem = await this.usertogroupRepository.findOne({
      where: { useruuid: user.id, groupuuid: groupItem.id },
    });
    if (oldItem) {
      return '您已经加入了该小组';
    } else {
      const rawUserToGroupDto = new RawUserToGroupDto();
      rawUserToGroupDto.useruuid = user.id;
      rawUserToGroupDto.role = userRoleEnum.member;
      rawUserToGroupDto.groupnickname = user.username;
      rawUserToGroupDto.groupuuid = groupItem.id;
      const insertItem = this.usertogroupRepository.create(rawUserToGroupDto);
      this.usertogroupRepository.insert(insertItem);
      return `加入${groupItem.group_name}小组成功`;
    }
  }

  createUserToGroupItem(rawUserToGroupDto: RawUserToGroupDto) {
    const insertItem = this.usertogroupRepository.create(rawUserToGroupDto);
    this.usertogroupRepository.insert(insertItem);
    return '创建成功';
  }
  async updateUserToGroupItem(
    id: string,
    updateUserToGroupDto: UpdateUserToGroupDto,
  ) {
    const oldItem = await this.usertogroupRepository.findOne({
      where: { id: id },
    });
    if (!oldItem) {
      return '该修改对象不存在';
    }
    const updateUserToGroup = Object.assign(oldItem, updateUserToGroupDto);
    await this.usertogroupRepository.save(updateUserToGroup);
    return '修改属性成功！';
  }
  async remove(id: string) {
    try {
      // 0.查询出
      const removeItem = await this.usertogroupRepository.findOne({
        where: { id },
      });
      const userItem = await this.userRepository.findOne({
        where: { id: removeItem.useruuid },
      });
      if (!removeItem || !userItem) {
        throw new Error('未找到用户');
      }
      const userToGroupItem = await this.usertogroupRepository.findOne({
        where: { groupuuid: removeItem.groupuuid, role: 'creator' },
      });
      const creatorInfo = await this.userRepository.findOne({
        where: { id: userToGroupItem.useruuid },
      });
      const groupuuid = removeItem.groupuuid;
      const email = userItem.email;
      // 1. 文件归属创建人
      const fileList = await this.groupToFlielistRepository.find({
        where: { belong: email, groupuuid: groupuuid },
        select: ['id'],
      });
      await this.groupToFlielistRepository.update(
        { id: In(fileList.map((file) => file.id)) },
        { belong: creatorInfo.email },
      );
      // 2.文件夹归属创建人
      const folderList = await this.groupToFolderRepository.find({
        where: { belong: email, groupuuid: groupuuid },
        select: ['id'],
      });
      await this.groupToFolderRepository.update(
        { id: In(folderList.map((file) => file.id)) },
        { belong: creatorInfo.email },
      );
      // 3.场景
      const scenceList = await this.groupToScenceRepository.find({
        where: { belong: email, groupuuid: groupuuid },
        select: ['id'],
      });
      await this.groupToScenceRepository.update(
        { id: In(scenceList.map((file) => file.id)) },
        { belong: creatorInfo.email },
      );
      // 4.脚本
      const scriptList = await this.groupToScriptRepository.find({
        where: { belong: email, groupuuid: groupuuid },
        select: ['id'],
      });
      await this.groupToScriptRepository.update(
        { id: In(scriptList.map((file) => file.id)) },
        { belong: creatorInfo.email },
      );
      // 5. 分享
      const shareList = await this.groupToShareRepository.find({
        where: { sharer: email, groupuuid: groupuuid },
        select: ['id'],
      });
      await this.groupToShareRepository.update(
        { id: In(shareList.map((file) => file.id)) },
        { sharer: creatorInfo.email },
      );
      // 退出小组
      await this.usertogroupRepository.delete({ id: id });
      return '退出成功';
    } catch (e) {
      console.log(e);
      return '退出失败';
    }
  }

  async deleteGroupToUser(groupuuid: string) {
    try {
      const result = await this.usertogroupRepository.delete({
        groupuuid: groupuuid,
      });
      if (result.affected && result.affected > 0) {
        return `成功删除 ${result.affected} 条记录`;
      } else {
        return `未找到匹配的记录，没有进行删除操作`;
      }
    } catch (err) {
      console.error('删除记录失败', err);
      throw '删除记录失败';
    }
  }
}
